home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / src / alloca.c < prev    next >
C/C++ Source or Header  |  1995-09-10  |  2KB  |  115 lines

  1.  
  2. /****************************************************************************
  3.  *
  4.  *  alloca() implementation for SAS/C
  5.  *
  6.  *  Copyright: PUBLIC DOMAIN
  7.  *  Written by Stefan Proels <proels@fmi.uni-passau.de>
  8.  *
  9.  */
  10.  
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. /*#include <clib/alib_protos.h>*/
  16. #include <constructor.h>
  17.  
  18. APTR __stdargs LibCreatePool(unsigned long, unsigned long, unsigned long);
  19. void __stdargs LibDeletePool(APTR);
  20. void __stdargs LibFreePooled(APTR, APTR, unsigned long);
  21. APTR __stdargs LibAllocPooled(APTR, unsigned long);
  22.  
  23. #ifndef __SASC
  24. #error Wrong compiler (SAS/C required)
  25. #endif
  26.  
  27. #ifdef _PROFILE
  28. #error This file must NOT be compiled with PROFILE enabled
  29. #endif
  30.  
  31.  
  32. /*
  33.  * each alloca()ted block is preceded by this header
  34.  */
  35. struct block
  36.   {
  37.     struct block *down;
  38.     ULONG size;
  39.     ULONG level;
  40.     /* alloca()ted memory below */
  41.   };
  42.  
  43. static APTR pool = NULL;
  44. static struct block *top = NULL;
  45. ULONG __alloca_SP = 0;
  46.  
  47.  
  48. /*
  49.  * SAS/C autoinitialization function
  50.  */
  51. PROFILE_CONSTRUCTOR(Sprof)
  52. {
  53.   if (pool = LibCreatePool(MEMF_ANY, 4096, 2048))
  54.     return 0;
  55.   return -1;
  56. }
  57.  
  58. /*
  59.  * SAS/C autotermination function
  60.  */
  61. PROFILE_DESTRUCTOR(Sprof)
  62. {
  63.   if (pool)
  64.     LibDeletePool(pool);
  65. }
  66.  
  67.  
  68. /*
  69.  * called whenever a function is entered
  70.  */
  71. void __asm _PROLOG(register __a0 char *dummy)
  72. {
  73.   __alloca_SP++;
  74. }
  75.  
  76. /*
  77.  * called on return from a function
  78.  */
  79. void __asm _EPILOG(register __a0 char *dummy)
  80. {
  81.   struct block *mem;
  82.  
  83.   for (mem = top; mem && mem->level >= __alloca_SP; mem = top)
  84.     {
  85.       top = mem->down;
  86.       LibFreePooled(pool, mem, mem->size);
  87.     }
  88.   --__alloca_SP;
  89. }
  90.  
  91.  
  92. /*
  93.  * that's what the whole thing is all about -- alloca()te memory
  94.  */
  95. void *alloca(size_t size)
  96. {
  97.   struct block *mem;
  98.  
  99.   if (size <= 0)  /* garbage collection -- not required */
  100.     return NULL;
  101.  
  102.   size += sizeof(struct block);
  103.   if (!(mem = (struct block *)LibAllocPooled(pool, (ULONG)size)))
  104.     {
  105.       /* do whatever you want here */
  106.       abort();
  107.     }
  108.   mem->down = top;
  109.   mem->size = size;
  110.   mem->level = __alloca_SP;
  111.   top = mem;
  112.   return ++mem;
  113. }
  114.  
  115.